#pragma once

struct RenderTask;

struct SubRenderPhase:
	public ICriticalSection
{
	GLFramebuffer*				m_fbo;
	std::vector<RenderTask*>	m_rendertasks;

	SubRenderPhase() :
		ICriticalSection(1)
	{}
};

class IRenderPhase
{
public:
	IRenderPhase();
	virtual ~IRenderPhase();

	bool					IsInitialized() const;
	virtual void			Initialize(GLTexture* output);

	virtual void			SortTasks(uint fboid);
	virtual void			AddTask(RenderTask* task);

	virtual void			PreFramebufferBind(uint fboid);
	virtual void			PostFramebufferBind(uint fboid);

	virtual void			PreTaskRender(uint fboid, RenderTask* task);
	virtual void			PostTaskRender(uint fboid, RenderTask* task);

	virtual void			BindMaterial(RenderTask* task);
	void					BindCamera();

	virtual void			PrePostprocess();
	virtual void			PostPostprocess();

	virtual void			PrePhase();
	virtual void			PostPhase();

	uint			GetNumFramebuffers();
	uint			GetNumPostprocesses();

	uint			GetPriority() const;
	void					SetPriority(uint priority);

	ICamera*				GetCamera();
	void					SetCamera(ICamera* camera, uint camarg);

	SceneInstance*			GetScene();
	void					SetScene(SceneInstance* scene);

	void					SetName(const std::string& name);
	const std::string&		GetName();

	void					Process();

protected:
	bool					m_initialized;
	std::string				m_name;
	ICamera*				m_sceneCamera;
	uint			m_camarg;

	SceneInstance*			m_sceneInstance;

	void					AddTaskToVector(uint fboid, RenderTask* task);
	void					LockTaskVectors();
	void					UnlockTaskVectors();
	SubRenderPhase*			CreateSubRenderPhase();

	void					SetPostprocessInput(GLTexture* texture);
	void					SetPostprocessOutput(GLTexture* texture);

	void					AddPostprocess(IPostprocess* postprocess);
	std::vector<RenderTask*>& GetRenderTasks(uint fboid);

private:
	std::vector<IPostprocess*>		m_postprocess;
	std::vector<SubRenderPhase*>	m_subphases;
	GLTexture*						m_inputPPFX;
	GLTexture*						m_outputPPFX;
	GLFramebuffer*					m_lastFBO;
	uint					m_priority;
	bool							m_taskVectorEnabled;
};

